package com.breeze.components.oss.mybaits.entity;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.breeze.components.mybatis.base.BaseEntity;
import com.mybatisflex.annotation.Table;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serial;
import java.io.Serializable;
import java.util.Objects;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.hash.HashInfo;

/**
 * 文件记录表 实体类。
 *
 * @author breeze
 * @since 2024-05-13 10:08:23
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Schema(title = "文件记录表")
@Table("sys_file_detail")
public class FileDetailDo extends BaseEntity implements Serializable {

  @Serial private static final long serialVersionUID = 1L;

  /** 文件访问地址 */
  @Schema(title = "文件访问地址")
  private String url;

  /** 文件大小，单位字节 */
  @Schema(title = "文件大小，单位字节")
  private Long size;

  /** 文件名称 */
  @Schema(title = "文件名称")
  private String filename;

  /** 原始文件名 */
  @Schema(title = "原始文件名")
  private String originalFilename;

  /** 基础存储路径 */
  @Schema(title = "基础存储路径")
  private String basePath;

  /** 存储路径 */
  @Schema(title = "存储路径")
  private String path;

  /** 文件扩展名 */
  @Schema(title = "文件扩展名")
  private String ext;

  /** MIME类型 */
  @Schema(title = "MIME类型")
  private String contentType;

  /** 存储平台 */
  @Schema(title = "存储平台")
  private String platform;

  /** 缩略图访问路径 */
  @Schema(title = "缩略图访问路径")
  private String thUrl;

  /** 缩略图名称 */
  @Schema(title = "缩略图名称")
  private String thFilename;

  /** 缩略图大小，单位字节 */
  @Schema(title = "缩略图大小，单位字节")
  private Long thSize;

  /** 缩略图MIME类型 */
  @Schema(title = "缩略图MIME类型")
  private String thContentType;

  /** 文件所属对象id */
  @Schema(title = "文件所属对象id")
  private String objectId;

  /** 文件所属对象类型，例如用户头像，评价图片 */
  @Schema(title = "文件所属对象类型，例如用户头像，评价图片")
  private String objectType;

  /** 文件元数据 */
  @Schema(title = "文件元数据")
  private String metadata;

  /** 文件用户元数据 */
  @Schema(title = "文件用户元数据")
  private String userMetadata;

  /** 缩略图元数据 */
  @Schema(title = "缩略图元数据")
  private String thMetadata;

  /** 缩略图用户元数据 */
  @Schema(title = "缩略图用户元数据")
  private String thUserMetadata;

  /** 附加属性 */
  @Schema(title = "附加属性")
  private String attr;

  /** 文件ACL */
  @Schema(title = "文件ACL")
  private String fileAcl;

  /** 缩略图文件ACL */
  @Schema(title = "缩略图文件ACL")
  private String thFileAcl;

  /** 哈希信息 */
  @Schema(title = "哈希信息")
  private String hashInfo;

  /** 上传ID，仅在手动分片上传时使用 */
  @Schema(title = "上传ID，仅在手动分片上传时使用")
  private String uploadId;

  /** 上传状态，仅在手动分片上传时使用，1：初始化完成，2：上传完成 */
  @Schema(title = "上传状态，仅在手动分片上传时使用，1：初始化完成，2：上传完成")
  private Integer uploadStatus;

  /** 将 FileInfo 转为 FileDetail */
  public static FileDetailDo toFileDetail(FileInfo info) {
    if (Objects.isNull(info)) {
      return null;
    }
    var detail =
        BeanUtil.copyProperties(
            info,
            FileDetailDo.class,
            "metadata",
            "userMetadata",
            "thMetadata",
            "thUserMetadata",
            "attr",
            "hashInfo");
    if (StrUtil.isNotEmpty(info.getId())) {
      detail.setId(Long.valueOf(info.getId()));
    }
    // 这里手动获 元数据 并转成 json 字符串，方便存储在数据库中
    detail.setMetadata(JSON.toJSONString(info.getMetadata()));
    detail.setUserMetadata(JSON.toJSONString(info.getUserMetadata()));
    detail.setThMetadata(JSON.toJSONString(info.getThMetadata()));
    detail.setThUserMetadata(JSON.toJSONString(info.getThUserMetadata()));
    // 这里手动获 取附加属性字典 并转成 json 字符串，方便存储在数据库中
    detail.setAttr(JSON.toJSONString(info.getAttr()));
    // 这里手动获 哈希信息 并转成 json 字符串，方便存储在数据库中
    detail.setHashInfo(JSON.toJSONString(info.getHashInfo()));
    return detail;
  }

  /** 将 FileDetail 转为 FileInfo */
  public static FileInfo toFileInfo(FileDetailDo detail) {
    if (Objects.isNull(detail)) {
      return null;
    }
    var info =
        BeanUtil.copyProperties(
            detail,
            FileInfo.class,
            "metadata",
            "userMetadata",
            "thMetadata",
            "thUserMetadata",
            "attr",
            "hashInfo");
    if (Objects.nonNull(detail.getId())) {
      info.setId(String.valueOf(detail.getId()));
    }
    // 这里手动获取数据库中的 json 字符串 并转成 元数据，方便使用
    info.setMetadata(JSON.parseObject(detail.getMetadata(), new TypeReference<>() {}));
    info.setUserMetadata(JSON.parseObject(detail.getUserMetadata(), new TypeReference<>() {}));
    info.setThMetadata(JSON.parseObject(detail.getThMetadata(), new TypeReference<>() {}));
    info.setThUserMetadata(JSON.parseObject(detail.getThUserMetadata(), new TypeReference<>() {}));
    // 这里手动获取数据库中的 json 字符串 并转成 附加属性字典，方便使用
    info.setAttr(JSON.parseObject(detail.getAttr(), Dict.class));
    // 这里手动获取数据库中的 json 字符串 并转成 哈希信息，方便使用
    info.setHashInfo(JSON.parseObject(detail.getHashInfo(), HashInfo.class));
    return info;
  }
}
